package com.skali.cab;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.portlet.ActionRequest;
import javax.portlet.ActionResponse;
import javax.portlet.PortletException;
import javax.portlet.PortletSession;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
import javax.portlet.ResourceRequest;
import javax.portlet.ResourceResponse;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.liferay.portal.kernel.exception.SystemException;
import com.liferay.portal.kernel.json.JSONArray;
import com.liferay.portal.kernel.json.JSONFactoryUtil;
import com.liferay.portal.kernel.json.JSONObject;
import com.liferay.portal.kernel.search.FacetedSearcher;
import com.liferay.portal.kernel.search.Field;
import com.liferay.portal.kernel.search.Hits;
import com.liferay.portal.kernel.search.Indexer;
import com.liferay.portal.kernel.search.OpenSearch;
import com.liferay.portal.kernel.search.OpenSearchUtil;
import com.liferay.portal.kernel.search.SearchContext;
import com.liferay.portal.kernel.search.SearchContextFactory;
import com.liferay.portal.kernel.search.SearchEngineUtil;
import com.liferay.portal.kernel.search.SearchException;
import com.liferay.portal.kernel.search.facet.AssetEntriesFacet;
import com.liferay.portal.kernel.search.facet.Facet;
import com.liferay.portal.kernel.search.facet.ScopeFacet;
import com.liferay.portal.kernel.search.facet.config.FacetConfiguration;
import com.liferay.portal.kernel.search.facet.config.FacetConfigurationUtil;
import com.liferay.portal.kernel.search.facet.util.FacetFactoryUtil;
import com.liferay.portal.kernel.util.ParamUtil;
import com.liferay.portal.kernel.util.StringPool;
import com.liferay.portal.kernel.util.Validator;
import com.liferay.portal.kernel.util.WebKeys;
import com.liferay.portal.kernel.xml.Document;
import com.liferay.portal.kernel.xml.DocumentException;
import com.liferay.portal.kernel.xml.Element;
import com.liferay.portal.kernel.xml.SAXReaderUtil;
import com.liferay.portal.model.Portlet;
import com.liferay.portal.service.PortletLocalServiceUtil;
import com.liferay.portal.theme.ThemeDisplay;
import com.liferay.portal.util.PortalUtil;
import com.liferay.portal.util.PortletKeys;
import com.liferay.portlet.documentlibrary.model.DLFileEntry;
import com.liferay.util.bridges.mvc.MVCPortlet;
import com.skali.cabdirectories.NoSuchCABDirectory_DLFileEntryMappingException;
import com.skali.cabdirectories.model.CABDirectories_Metadata;
import com.skali.cabdirectories.model.CABDirectory_DLFileEntryMapping;
import com.skali.cabdirectories.service.CABDirectories_MetadataLocalServiceUtil;
import com.skali.cabdirectories.service.CABDirectory_DLFileEntryMappingLocalServiceUtil;
import com.skali.portal.util.Constants;

/**
 * Portlet implementation class CABDirectoriesDisplay
 */
public class CABDirectoriesDisplay extends MVCPortlet {
	
	@Override
	public void doView(RenderRequest renderRequest,
			RenderResponse renderResponse) throws IOException, PortletException {

		//	CABDirectories_MetadataLocalServiceUtil.se
		super.doView(renderRequest, renderResponse);
	}
	
	
	
	/**
	 * This method is called each new character-entry in the search-Filters[acb-no,org-name,field,etc] 
	 * via a ajax call and returns the filtered search results
	 */
	@Override
	public void serveResource(ResourceRequest  resourceRequest,
			ResourceResponse resourceResponse) throws IOException, PortletException {

		String acb_no  = ParamUtil.getString(resourceRequest, "acbno");
		String orgName = ParamUtil.getString(resourceRequest, "orgName");
		String field = ParamUtil.getString(resourceRequest, "field");
		String cabSearchType = ParamUtil.getString(resourceRequest, "cabSearchType");
		String searchKeyword = ParamUtil.getString(resourceRequest, "keyword");
		String scopeUrl = StringPool.BLANK;
			
		String sammNo  = ParamUtil.getString(resourceRequest, "sammNo");
		if(Validator.isNotNull(sammNo) && (!sammNo.isEmpty())){
			getCabDetailsBySammNo(sammNo ,resourceRequest,resourceResponse);
		}else{
			
			List<CABDirectories_Metadata> cabDirectories_MetadataLIST = new ArrayList<CABDirectories_Metadata>();
			HashMap<String, Object> searchFieldsMap =  new HashMap<String, Object>();
			searchFieldsMap.put(Constants.CabType, cabSearchType);
			searchFieldsMap.put(Constants.SammNo, acb_no);
			searchFieldsMap.put(Constants.OrganizationName, orgName);
			searchFieldsMap.put(Constants.Field, field);
			searchFieldsMap.put(Constants.SearchKeyword, searchKeyword);

			try{
				boolean isSearchParamsEmpty =((acb_no.isEmpty())&&(orgName.isEmpty())&&(field.isEmpty()))? true:false;
				
				System.out.println("cabDirectories_MetadataLIST size Before getMergedCABDirectoryList mthd >>> "+cabDirectories_MetadataLIST.size());
				if(searchKeyword.isEmpty()){
					System.out.println("INSIDE CONDITION_/E && E/---A");
					cabDirectories_MetadataLIST = CABDirectories_MetadataLocalServiceUtil.fetchByCustomCabDirectories_MetadataFields(searchFieldsMap);
				
				}else if((!searchKeyword.isEmpty()) && (isSearchParamsEmpty)){
					System.out.println("INSIDE CONDITION_/NE && E/---B");
					// Incase 'isSearchParamsEmpty'is empty ...still need to search the Entity for the searchKeyword..
					cabDirectories_MetadataLIST = CABDirectories_MetadataLocalServiceUtil.fetchByCustomCabDirectories_MetadataFields(searchFieldsMap);
					cabDirectories_MetadataLIST = getMergedCABDirectoryList(resourceRequest,cabDirectories_MetadataLIST,searchKeyword,isSearchParamsEmpty);
			
				}else if((!searchKeyword.isEmpty()) && (!isSearchParamsEmpty)){
					System.out.println("INSIDE CONDITION_/NE && NE/---C");
					cabDirectories_MetadataLIST = CABDirectories_MetadataLocalServiceUtil.fetchByCustomCabDirectories_MetadataFields(searchFieldsMap);
					cabDirectories_MetadataLIST = getMergedCABDirectoryList(resourceRequest,cabDirectories_MetadataLIST,searchKeyword,isSearchParamsEmpty);
				}
					
				System.out.println("cabDirectories_MetadataLIST size After getMergedCABDirectoryList mthd >>> "+cabDirectories_MetadataLIST.size());
				
				JSONArray jsonArray = JSONFactoryUtil.createJSONArray();
				if(!cabDirectories_MetadataLIST.isEmpty()){
					
					for(CABDirectories_Metadata list : cabDirectories_MetadataLIST){

						try{
							/**
							 * Converting the List<CABDirectories_Metadata> into a JsonArray..
							 */
							scopeUrl = PortalUtil.getPortalURL(resourceRequest)+"/"+list.getScope();

							JSONArray innerArray = JSONFactoryUtil.createJSONArray();
							innerArray.put(list.getSammNo());
							innerArray.put("<a data-toggle='modal' href='#' onClick='return invokePopUp("+list.getSammNo()+");'>"+list.getOrganizationName()+"</a>");
							innerArray.put(list.getField());
							innerArray.put("<a href='"+scopeUrl+"' target='_blank'>View</a>" );
							jsonArray.put(innerArray);
							
						}catch(Exception e){
							e.getMessage();
						}
					}
				}else{
					System.out.println(" NO RESULTS FOUND --CABDirectories_Metadata LIST = EMPTY");
				}

				doResponseAjaxCall(jsonArray.toString(),resourceRequest, resourceResponse);

				JSONObject jsonCapsule = JSONFactoryUtil.createJSONObject();
				jsonCapsule.put("aaData", jsonArray);
				//	doResponseAjaxCall(jsonCapsule.toString(),resourceRequest, resourceResponse);
			//	System.out.println("after.............. jsonCapsule = "+jsonCapsule);

			}catch(NullPointerException npe){
				System.out.println(" NullPointerException caught >>> "+npe.getMessage());
				npe.printStackTrace();
				
			}catch(Exception e){
				e.printStackTrace();
			}
		}
	
	}
	
	
	

	 private void getCabDetailsBySammNo(String sammNo, ResourceRequest resourceRequest, ResourceResponse resourceResponse) {
		// TODO Auto-generated method stub
		 System.out.println("sammNo recevd in getCabDetailsBySammNo = "+sammNo);
		 
		 HttpServletResponse httpServletResponse =  PortalUtil.getHttpServletResponse(resourceResponse);
		 HttpServletRequest httpServletRequest =  PortalUtil.getHttpServletRequest(resourceRequest);
		 httpServletRequest.setAttribute("sammNo", sammNo);
		 ServletContext servletContext = httpServletRequest.getSession().getServletContext();
		 String jspFile = "";
		 
		 try{
			 jspFile = PortalUtil.renderPage(servletContext, httpServletRequest, httpServletResponse, "/html/cabdirectoriesdisplay/viewDetails.jsp", false);
		 }catch(ServletException e){
			 e.printStackTrace();
		 } catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		 
		 /**
		  * sending back Response to AjaxCall here..
		  */
		 PrintWriter pw ;
			try {
				pw = httpServletResponse.getWriter();
			//	System.out.println(" jspFile - to string >>>>>> "+jspFile);
				pw.println(jspFile);
				pw.flush();
				pw.close();
			} catch (IOException e) {
				e.printStackTrace();
			}catch(Exception e){
				e.printStackTrace();
			}
	}

	 
	 
	 
	 
	 
	 
	 
	 
	 
	 
	 
	 
	 


	/**
	  * This method will merge the...
	 * @param resourceRequest 
	 * @param List<CABDirectories_Metadata> 
	 * @param searchKeyword 
	 * @param doMerge 
	 */ 
	private List<CABDirectories_Metadata> getMergedCABDirectoryList(
			ResourceRequest resourceRequest, List<CABDirectories_Metadata> cabDirectories_MetadataLIST, String searchKeyword, boolean isSearchParamsEmpty) {

		System.out.println("Inside getMergedCABDirectoryList >>>>> isSearchParamsEmpty = "+isSearchParamsEmpty);
		List<Long> dlFileEntryIds = new ArrayList<Long>();
		PortletSession portletSession = resourceRequest.getPortletSession();
		
		if(!searchKeyword.isEmpty()){	
			
			if((portletSession.getAttribute(Constants.SearchKeyword)!=null) && portletSession.getAttribute(Constants.SearchKeyword).toString().equalsIgnoreCase(searchKeyword)){
				dlFileEntryIds = (List<Long>)portletSession.getAttribute(Constants.DLFileEntryIds);
				System.out.println(">>>>>>  SearchKeyword found in session <<<<< with list size =  "+dlFileEntryIds.size());
			}else{
				System.out.println(">>>>>>  SearchKeyword NOT found in session <<<<<< ");
				dlFileEntryIds =	doPerformCustomFacetedSearch(resourceRequest , searchKeyword);
				//System.out.println(">>>>>>  Search Results -- dlFileEntryIds.size =   "+dlFileEntryIds.size());
				portletSession.setAttribute(Constants.SearchKeyword, searchKeyword);
				portletSession.setAttribute(Constants.DLFileEntryIds, dlFileEntryIds);
			}
		}
	//	 printcabDirectories_MetadataLIST(cabDirectories_MetadataLIST);
		
		 System.out.println(" cabDirectories_MetadataLIST-size recevd in getMergedCABDirectoryList >>>  "+cabDirectories_MetadataLIST.size());
		
	 
		 for(Long fileEntryId: dlFileEntryIds){
			
			long sammNo;
			CABDirectories_Metadata cabDirectory = null;
			boolean add_entry_in_CabList = false;
			
			try {
				sammNo = CABDirectory_DLFileEntryMappingLocalServiceUtil.findByFileEntryId(fileEntryId).getSammId();
				System.out.println("sammNo -- "+sammNo);
				cabDirectory = CABDirectories_MetadataLocalServiceUtil.fetchCABDirectories_Metadata(sammNo);
				
				System.out.println("cabDirectory.getOrganizationName -- "+cabDirectory.getOrganizationName());
				//	if(!isSearchParamsEmpty){
						if(Validator.isNotNull(cabDirectory)){
							for(CABDirectories_Metadata list:cabDirectories_MetadataLIST){
							
								System.out.println(cabDirectory.getOrganizationName()+" >>> list.getSammNo() == "+list.getSammNo()+" --  cabDirectory.getSammNo()== "+cabDirectory.getSammNo());
								
								if(list.getSammNo()==cabDirectory.getSammNo() ){								
									add_entry_in_CabList = true;
									System.out.println(" inside if -list.getSammNo()==cabDirectory.getSammNo() -->>>>");
								//	break;
								}
							}
		
						}
					
				//	}
			
				System.out.println(cabDirectory.getOrganizationName()+" >> add_entry_in_CabList== "+add_entry_in_CabList);
				if(!add_entry_in_CabList){
					System.out.println(cabDirectory.getOrganizationName()+" doc-serach-Entry Not found in original Cab List ...Hence wud be Added hereby..");
				
					cabDirectories_MetadataLIST.add(cabDirectory);

				}else{
					System.out.println(cabDirectory.getOrganizationName()+" doc-serach Entry Found in original Cab List ...");
				}

			} catch (NoSuchCABDirectory_DLFileEntryMappingException e) {
				e.printStackTrace();
			} catch (SystemException e) {
				e.printStackTrace();
			}catch(NullPointerException npe){
				System.out.println(">> NullPointerException caught in getMergedCABDirectoryList >>  "+npe.getMessage());
			}

		}
		
		return cabDirectories_MetadataLIST;
	}



	private void printcabDirectories_MetadataLIST(
			List<CABDirectories_Metadata> cabDirectories_MetadataLIST) {
		
		System.out.println("---------------START----------- ");
		for(CABDirectories_Metadata list:cabDirectories_MetadataLIST){
			System.out.println(" list- "+list.getOrganizationName());
		}
		System.out.println("---------------START----------- ");
	}



	/**
	 * This method will perform the custom Doc Search as Liferay faceted-Search &&
	 *  returns the list of fileEntryIds of the ResultEntries Found..
	 */
	private List<Long> doPerformCustomFacetedSearch(ResourceRequest resourceRequest,
			String searchKeyword) {

		System.out.println(" searchKeyword recevd in doPerformCustomFacetedSearch >>> "+searchKeyword);
		
		HttpServletRequest request = PortalUtil.getHttpServletRequest(resourceRequest);
		SearchContext searchContext = SearchContextFactory.getInstance(request);
		searchContext.setKeywords(searchKeyword);
		searchContext.setEnd(2000);
		searchContext.setStart(0);

		/*	Facet assetEntriesFacet = new AssetEntriesFacet(searchContext);
		assetEntriesFacet.setStatic(true);
		searchContext.addFacet(assetEntriesFacet);
		Facet scopeFacet = new ScopeFacet(searchContext);
		scopeFacet.setStatic(true);
		searchContext.addFacet(scopeFacet);

		List<FacetConfiguration> facetConfigurations = FacetConfigurationUtil.load(searchConfiguration);

		for (FacetConfiguration facetConfiguration : facetConfigurations) {
			Facet facet = FacetFactoryUtil.create(searchContext, facetConfiguration);

			searchContext.addFacet(facet);
		}*/


		Indexer indexer = FacetedSearcher.getInstance();

		Hits hits = null;
		try {
			hits = indexer.search(searchContext);
			//String[] queryTerms = hits.getQueryTerms();
		} catch (SearchException srhe) {
			System.out.println(" SearchException caught >>> "+srhe.getMessage());
			srhe.printStackTrace();
		}
		List<Long> dlFileEntryIds = new ArrayList<Long>();
		try{
			List<com.liferay.portal.kernel.search.Document> documents = hits.toList();
			if(!documents.isEmpty()){
				System.out.println(" docs size = "+documents.size());
				System.out.println("--------------------------");
				for(com.liferay.portal.kernel.search.Document doc : documents){
					
					String docEntryClassName = doc.get(Field.ENTRY_CLASS_NAME);
					long dlFileEntryId =0;
					System.out.println(" found in search-results Entries  >>>>>>>>>>ENTRY_CLASS_NAME "+doc.get(Field.ENTRY_CLASS_NAME)+
							"ENTRY_CLASS_PK found in search results doc's >>>>>>>>>> "+doc.get(Field.ENTRY_CLASS_PK));
					if(DLFileEntry.class.getName().equalsIgnoreCase(docEntryClassName)){
						dlFileEntryId = Long.valueOf(doc.get(Field.ENTRY_CLASS_PK).toString());
						dlFileEntryIds.add(dlFileEntryId);
					}
				}
				System.out.println("--------------------------");
				
			}else{
				System.out.println(" >>>>>>>> empty docs list recevd <<<<<<<<");
			}
		}catch(Exception e){
			e.printStackTrace();
		}

		return dlFileEntryIds;
	}



	/** this method is just for responding back the ajax call..
	 * @param jsonCapsule 
	 *  @param ResourceRequest 
	 *  @param ResourceResponse 
	 */
	private void doResponseAjaxCall(String jsonCapsule, ResourceRequest resourceRequest, ResourceResponse resourceResponse) {

		PrintWriter pw ;
		HttpServletResponse httpServletResponse =  PortalUtil.getHttpServletResponse(resourceResponse);
		try {
			httpServletResponse.setContentType("application/json");
			pw = httpServletResponse.getWriter();
			/*pw.write(PortalUtil.getLayoutURL(themeDisplay).toString());*/
			System.out.println(" jsonarray - to string >>>>>> "+jsonCapsule);
			pw.println(jsonCapsule);
			pw.flush();
			pw.close();
		} catch (IOException e) {
			e.printStackTrace();
		}catch(Exception e){
			e.printStackTrace();
		}
	}


	
	private void docallTestMethod(ResourceRequest resourceRequest,
			ResourceResponse resourceResponse) {

		//OpenSearchUtil.
		//	SearchEngineUtil.se
		ThemeDisplay themDisplay = (ThemeDisplay) resourceRequest.getAttribute(WebKeys.THEME_DISPLAY);
		Portlet portlet = null;
		String plid = StringPool.BLANK;
		OpenSearch openSearch;
		String searchResult = StringPool.BLANK;
		System.out.println(" >>> inside docallTestMethod >>>>>> "+searchResult);
		
		try {

			portlet = PortletLocalServiceUtil.getPortletById(themDisplay.getCompanyId(), PortletKeys.DOCUMENT_LIBRARY_DISPLAY);

			openSearch = portlet.getOpenSearchInstance();
			HttpServletRequest httpServletRequest = PortalUtil.getHttpServletRequest(resourceRequest);
			try {
				searchResult = openSearch.search(httpServletRequest , "testblog");
				System.out.println(" >>> searchResult >>>>>> "+searchResult);

			} catch (SearchException e) {
				System.out.println(">>>>>>>>>> inside SearchException >>>>>>>> ");
				e.printStackTrace();
			}

			plid =portlet.getPortletId();
			System.out.println("plid for BLOGS ==  "+plid);
		} catch (SystemException se) {
			System.out.println(">>>>>>>>>> inside SystemException 555 >>>>>>>> ");
			se.printStackTrace();
		}catch(Exception e){
			System.out.println(">>>>>>>>>> inside Exception 555 >>>>>>>> ");
			e.printStackTrace();
		}
		
	}

	
	
	
	
	
	
	
	
	
	/*private void getParsedXmlValues(String xml) {
		
		System.out.println(" inside getParsedXmlValues >>> ");
		
		Document document;
		Element rootElement;
	//	List<Element> elementList;
		try {
			document = SAXReaderUtil.read(xml);
			rootElement = document.getRootElement();

			System.out.println(" rootElement asXML ->>>>> "+rootElement.asXML());

			getParsedElements(rootElement);

		} catch (DocumentException e) {
			e.printStackTrace();
		}catch(Exception e ){
			e.printStackTrace();
		}
		
	}*/
	
	
	/**
	 * 	  rootElement asXML ->>>>>
	 *  <root>
			<dynamic-element name="field">
		 		<dynamic-content><![CDATA[liferay]]></dynamic-content>
			</dynamic-element>
		 	<dynamic-element name="acb_no">
				<dynamic-content><![CDATA[121]]></dynamic-content>
		 	</dynamic-element>
			<dynamic-element name="organization_name">
		 		<dynamic-content><![CDATA[mpower]]></dynamic-content>
		 	</dynamic-element>
		 </root>
		*/
	
  /**
   * childElement.asXML() >>>>>
  		<dynamic-element name="field">
	 		<dynamic-content><![CDATA[liferay]]></dynamic-content>
	 	</dynamic-element>
   */
	
	/*private void getParsedElements(Element rootElement) {

		List<Element> elementList;
		List<Element> childElementsList;
		Map<String, Object> mapObj = new HashMap<String, Object>();

		try{
			elementList = rootElement.elements();

			for(Element childElement :elementList){

				System.out.println(" childElement.asXML() >>>>> "+childElement.asXML());

				childElementsList = childElement.elements();
				if(!childElementsList.isEmpty()){

					for(Element subChild :childElementsList){
						String a;
						if(subChild.elementByID("acb_no")!=null){
							a=subChild.elementByID("acb_no").getStringValue();
							System.out.println("a in acb::"+a);
						}

						//	String subChildname = subChild.getName();
						//	System.out.println(" subChild.getName() >>>>> "+subChildname);
						getParsedElements(subChild);
					}
				}else {

					String name =  childElement.getName();

					if (name.equals("dynamic-content")) {

						Element nameElement = childElement.element("dynamic-content");
						//	Element valueElement = childElement.element("value");
						System.out.println(" nameElement.getText() >>>>> "+nameElement.getStringValue());
						//		System.out.println(" valueElement.getText() >>>>> "+valueElement.getText());

					}
				}
			}

		}catch(Exception e){
			e.printStackTrace();
		}
	}
*/

	
}
